#!/usr/bin/perl -w
# vim:tw=100 sw=2 expandtab ft=perl

use POSIX;

$m{$hostname}{_os_detection} = {
  type => 'unknown',
  os => 'unknown',
  distro => 'unknown',
  version => 'unknown',
  arch => 'unknown',
};
my $o = $m{$hostname}{_os_detection};
my($sysname, $nodename, $version, $release, $arch) = POSIX::uname();
$o->{version} = $version;
$o->{arch} = $arch;

if ($^O eq 'linux') {
  $o->{type} = 'unix';
  $o->{os} = 'linux';

  chomp($o->{distro} = lc `lsb_release -sd` || 'unknown');
  chomp($o->{version} = lc `lsb_release -sr` || 'unknown');

  # Specific distribution hacks
  $o->{distro} = 'ubuntu' if $o->{distro} =~ /^ubuntu/;
  $o->{distro} = 'centos' if $o->{distro} =~ /^centos/;
  $o->{distro} = 'redhat' if $o->{distro} =~ /^redhat/;
  $o->{distro} = 'redhat' if $o->{distro} =~ /^(?:enterprise)?enterprise[ae]s/;

} elsif ($^O eq 'freebsd') {
  $o->{type} = 'unix';
  $o->{os} = $o->{distro} = 'freebsd';

} elsif ($^O eq 'openbsd') {
  $o->{type} = 'unix';
  $o->{os} = $o->{distro} = 'openbsd';

} elsif ($^O eq 'sunos' || $^O eq 'solaris') {
  $o->{type} = 'unix';
  $o->{os} = $o->{distro} = 'solaris';

} elsif ($^O eq 'aix') {
  $o->{type} = 'unix';
  $o->{os} = $o->{distro} = 'aix';

} elsif ($^O eq 'hpux') {
  $o->{type} = 'unix';
  $o->{os} = $o->{distro} = 'hpux';

} elsif ($^O eq 'irix') {
  $o->{type} = 'unix';
  $o->{os} = $o->{distro} = 'irix';

} elsif ($^O eq 'darwin') {
  $o->{type} = 'unix';
  $o->{os} = $o->{distro} = 'macos';

} elsif (lc $^O eq 'mswin32' || $^O eq 'cygwin') {
  $o->{type} = 'windows';
  $o->{os} = 'windows';
  $o->{distro} = lc $^O;

} elsif ($^O eq 'amigaos' || $^O eq 'beos' || $^O eq 'dos' || $^O eq 'os2') {
  fatal "$^O! Go away!";

} else {
  w "Unknown sysname \"$^O\", OS detection won't work";
  return;
}

v "OS detection: type=$o->{type} os=$o->{os} distro=$o->{distro} version=$o->{version}";

sub i_unix { return $m{$hostname}{_os_detection}{type} eq 'unix' ? 1 : 0 }
sub i_os {
  return $m{$hostname}{_os_detection}{os} unless @_;
  foreach (@_) {
    return 1 if $m{$hostname}{_os_detection}{os} =~ /$_/i;
  }
  return 0;
}
sub i_distro {
  return $m{$hostname}{_os_detection}{distro} unless @_;
  foreach (@_) {
    return 1 if $m{$hostname}{_os_detection}{distro} =~ /$_/i;
  }
  return 0;
}
sub i_os_version { return $m{$hostname}{_os_detection}{version} }
